#ifndef __VM_KERNEL__
#define __VM_KERNEL__

#include <map>
#include "directory.h"
#include "thread.h"
#include "proc.h"
#include "cpu.h"
#include "kofs.h"
#include "helper.h"

namespace xm
{
	class thread_t;
	class process_t;
	enum thstate;

	static uint32_t alloctype_to_paga( uint32_t type, uint32_t paga )
	{
		if( type & MEM_TOP_DOWN )
			paga |= PGA_TOP_DOWN;
		if( type & MEM_COMMIT )
			paga |= PGA_COMMIT;
		if( type & MEM_RESERVE )
			paga |= PGA_REVERSE;
		return paga;
	}

	static uint32_t prot_to_paga( uint32_t prot, uint32_t paga )
	{
		if( prot & PAGE_NOACCESS )
			return paga;
		
		if( prot & PAGE_GUARD )
			paga |= PGA_GUARD;

		if( prot & 0xF0 )
		{
			paga |= PGA_EXECUTE;
			prot >>= 4;
		}

		if( prot & PAGE_READONLY )
			paga |= PGA_READ;
		
		if( prot & PAGE_WRITECOPY )
			paga |= (PGA_READ|PGA_WCOPY);

		if( prot & PAGE_READWRITE )
			paga |= (PGA_READ|PGA_WRITE);

		return paga;
	}
	
	class kernel_t
	{
	protected:

		std::vector< kop_t >	_holder;

	public:

		void	hold_object( kip_t ki )
		{
			if( !ki ) return ;
			if( S_OK == ki->UpdateScope(KoScopekernel) )
				_holder.push_back( ki );
		}

	public:

		ntcore_t&	ntk;

		kernel_t( ntcore_t & ofs_ );

		long init();

	protected:

		uint32_t	_clientid;

	public:
		
		//
		// client_id 0 means failed
		//

		uint32_t	client_id_alloc();
		
		void		client_id_free( uint32_t id );

	protected:
		
		//
		//	thread map
		//

		typedef std::map<uint32_t, optr<thread_t> > thread_map_t;

		thread_map_t		_thread_map;

		dllist<thread_t>	_thread_list;

		optr<thread_t>		_current_thread;

		optr<thread_t>		_current_process;

	public:

		optr<thread_t>		thread_create( process_t* proc, vxvma_t addr, size_t stack_size, size_t opts = TOPT_USER_THREAD, vxvma_t stackbase = 0 );

		void				thread_clear();

		long				thread_select( thread_t * to );

		thread_t*			thread_switch( bool noself = false );

		long				thread_erase( thread_t * to );

		thread_t *			current_thread() { return _current_thread; };

	protected:

		thread_t *			thread_find_by_state( thread_t* from, thstate state, bool noself );

	protected:

		//
		//	process map
		//

		typedef std::map<uint32_t, optr<process_t> > process_map_t;

		process_map_t		_process_map;

	public:

		process_t*			process_create( process_t * parent, uint32_t opt );

		void				process_init_peb32( PEB32 * peb );
		void				process_init_peb64( PEB64 * peb );

	public:

		//
		//	utils
		//

		kop_t				w32_search_find_path( LPCSTR curdir, LPCSTR name, size_t opt );

		long				map_named_object( KoScope scope, LPCSTR path, IKernelObject * obj );
		
	protected:

		rmb_t				_rmb_usd;

	public:

		rmb_t*				user_share_data_rmbp() { return &_rmb_usd; };

	};

};



#endif